/**
 * Copyright (c) 2006, PORTALIER Julien
 * 
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 * 
 * @package    FeatherCMS
 * @subpackage Javascript
 * @copyright  Copyright (c) 2006, Julien PORTALIER
 * @link       http://portalier.com/feather
 * @license    http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

var Toolbar = {};

Toolbar.Base = new Class(
{
	initialize: function(attachTo, options)
	{
		this.buttons = this.buttons || [];
		
		this.options = {
			className: 'toolbar',
			insert:    'Before'
		};
		this.options = Object.extend(this.options, options || {});
		
		// creation
		this.create();
		
		// events
		this.toolbar.addEvent('click', this.action.bind(this));
		
		// injects in DOM
		this.toolbar['inject' + this.options.insert](attachTo);
	},
	
	addButton: function(_id, _title, content)
	{
		this.toolbar.appendChild(
			new Element('a', {href: '#', id: _id, title: _title}, content || _id)
		);
	},
	
	addSeparator: function()
	{
		this.toolbar.appendChild(
			new Element('span', {'class': 'separator'})
		);
	},
	
	create: function()
	{
		this.toolbar = new Element('div', {'class': this.options.className});
		this.buttons.forEach(function(bt)
		{
			if (bt.length > 0) {
				this.addButton(bt[0], bt[1]);
			}
			else {
				this.addSeparator();
			}
		}, this);
	},
	
	action: function(evt)
	{
		evt = new Event(evt);
		evt.stop();
		
		var el = evt.target();
		while(el.getTag() != 'a')
		{
			if (el.hasClass('toolbar')) {
				return;
			}
			el = el.parentNode;
		}
		this['cb_' + el.id]();
	}
});

Toolbar.Text = Toolbar.Base.extend(
{
	initialize: function(textarea, options)
	{
		this.parent(textarea, options);
		this.textarea = $(textarea);
		this.textarea.addEvent('keypress', this.onShortcut.bind(this));
	},
	
	onShortcut: function(evt)
	{
		evt = new Event(evt);
		
		if (evt.modifier('ctrl') && !evt.modifier('alt'))
		{
			var k = evt.key().string.toLowerCase();
			
			this.buttons.each(function(bt)
			{
				if (bt.length > 2 && bt[2] == k)
				{
					this['cb_' + bt[0]]();
					evt.stop();
					$break();
				}
			}, this);
		}
	},
	
	// text selection
	
	getSelection: function()
	{
		if (document.selection)
		{
			var sel = document.selection.createRange();
			if (sel.parentElement && sel.parentElement().id != this.textarea.id) {
				return;
			}
			return sel.text;
		}
		else if (this.textarea.setSelectionRange)
		{
			var nStart = this.textarea.selectionStart;
			var nEnd   = this.textarea.selectionEnd;
			return this.textarea.value.substring(nStart, nEnd);
		}
	},
	
	replaceSelection: function(str)
	{
		if (document.selection)
		{
			var sel = document.selection.createRange();
			if (sel.parentElement().id != this.textarea.id) {
				return;
			}
			sel.text = str;
		}
		else if (this.textarea.setSelectionRange)
		{
			var scrollPos = this.textarea.scrollTop;
			var nStart    = this.textarea.selectionStart;
			var nEnd      = this.textarea.selectionEnd;
			var pos       = nStart + str.length;
			
			this.textarea.value = this.textarea.value.substring(0, nStart) + 
				str + this.textarea.value.substring(nEnd);
			this.textarea.setSelectionRange(pos, pos);
			this.textarea.scrollTop = scrollPos;
		}
		this.textarea.focus();
	},
	
	encloseSelection: function(open, close)
	{
		var text = open + this.getSelection() + (close || open);
		this.replaceSelection(text);
	},
	
	replaceInSelection: function(regexp, str, before)
	{
		var text = str + this.getSelection().replace(regexp, (before || '') + str);
		this.replaceSelection(text);
	}
});

Toolbar.Syntax = Toolbar.Text.extend(
{
	initialize: function(textarea, syntax)
	{
		this.buttons = [
			['more',       _('Expand textarea')],
			['less',       _('Shrink textarea')],
			[],
			['italic',     _('Emphasis (Ctrl+I)'),         'i'],
			['bold',       _('Bold (Ctrl+B)'),             'b'],
			['underline',  _('Underline (Ctrl+U)'),        'u'],
			['del',        _('Deleted (Ctrl+D)'),          'd'],
			[],
	//		['highlight',  _('Highlight')],
	//		['color',      _('Font color')],
	//		['sup',        _('Exponent')],
	//		['q',          _('Inline quote')],
	//		['br',         _('Line break')],
	//		[],
			['quote',      _('Blockquote (Ctrl+Q)'),       'q'],
			['pre',        _('Preformated text (Ctrl+P)'), 'p'],
			[],
			['link',       _('Insert link (Ctrl+L)'),      'l'],
			['media',      _('Display media (Ctrl+M)'),    'm']
		];
		
		this.syntax = 0;
		if (syntax)
		{
			this.selectSyntax = $(syntax);
			this.selectSyntax.addEvent('change', this.setSyntax.bind(this));
			this.setSyntax();
		}
		
		this.parent(textarea);
	},
	
	setSyntax: function()
	{
		this.syntax = parseInt(this.selectSyntax.value, 10);
	},
	/*
	addButton: function(tag, title)
	{
		this.parent(tag, title, new Element('img', {
			src: '/img/icons/toolbar/' + tag + '.png',
			alt: tag
		}));
	},
	*/
	
	// text selection
	
	encloseSelection: function(wiki, tag)
	{
		if (this.syntax === 0) {
			this.parent(wiki);
		} else {
			this.parent('<' + tag + '>', '</' + tag + '>');
		}
	},
	
	selectionStartLinesWith: function(str)
	{
		this.replaceInSelection(/\n/gi, str, '\n');
	},
	
	// callbacks
	
	cb_italic:    function() { this.encloseSelection('//', 'i');   },
	cb_bold:      function() { this.encloseSelection('**', 'b');   },
	cb_underline: function() { this.encloseSelection('__', 'u');   },
	cb_del:       function() { this.encloseSelection('~~', 'del'); },
	
	cb_quote: function()
	{
		if (this.syntax === 0) {
			this.selectionStartLinesWith('> ');
		} else {
			this.encloseSelection(null, 'blockquote');
		}
	},
	
	cb_pre: function()
	{
		if (this.syntax === 0) {
			this.selectionStartLinesWith(' ');
		} else {
			this.encloseSelection(null, 'pre');
		}
	},
	
	cb_link: function()
	{
		var url = prompt(_("Enter the URL to point to:"));
		if (url)
		{
			var str = this.getSelection(), text;
			if (!str) {
				str = prompt(_('Enter link title:'));
			}
			
			this.replaceSelection((this.syntax === 0) ?
				'"' + str + '":' + url :
				'<a href="' + url + '">' + str + '</a>'
			);
		}
	},
	
	cb_media: function()
	{
		var text;
		var url = prompt(_('Enter image location URL:'));
		if (url)
		{
			var str = this.getSelection();
			
			if (this.syntax === 0)
			{
				if (str) {
					str = '|' + str;
				}
				this.replaceSelection('{{' + url + str + '}}');
			}
			else {
				this.replaceSelection('<img src="' + url + '" title="' + str + '" alt="" />');
			}
			
		}
	},
	
	cb_more: function() { this.setHeight(+100); },
	cb_less: function() { this.setHeight(-100); },
	
	setHeight: function(offset)
	{
		var h = parseInt(this.textarea.getStyle('height'), 10);
		if (!this.fx) {
			this.fx = this.textarea.effect('height').set(h);
		}
		this.fx.goTo(h + offset);
		this.textarea.focus();
	}
});